
#include "../main.h"
#include "Tool.h"
#include <math.h>


_Pt1000_State Pt1000_State;


//卡马克快速求平方根的倒数(替换标准库sqrt函数): 比标准库函数快4倍
float InvSqrt(float number)
{
    long i;
    float x2, y;

    x2 = number * 0.5;
    y  = number;
    i  = *(long *)&y; //evil floating point bit level hacking
    i  = 0x5f3759df - (i >> 1); // 计算第一个近似根 // what the fuck?
    y  = *(float *)&i;
    y  = y * (1.5 - (x2 * y * y)); //牛顿迭代法 // 1st iteration 
    y  = y * (1.5 - (x2 * y * y)); //2nd iteration, this can be removed

    return y;
}

//输入10进制数,返回个位/十位/百位的数字
uint32_t GetNums(uint32_t dat,_Num_unit bit)
{
    uint32_t temp;

    temp = (dat / (bit * 1)) % 10;
    return temp;
}


//根据分压电路转换成电阻
//输入 12位AD, 输出对应的 电阻值
double AD_Convert_R(uint32_t ad)
{
    double temp;

    temp = ad;
    if(temp <= 500)
    {
        temp = 7192; //AD <= 500时,认为电阻有 7192 Ω
    }
    else if(temp >= 4096)
    {
        temp = 0; //最小电阻 0 Ω
    }
    else
    { //根据分压电路,得出AD转电阻的公式
        temp = (4096.0 / temp - 1.0) * 1000.0; //以VDD为AD参考源,根据分压电路推导出 12位AD值转电阻的公式:  R = ((4096/AD) - 1) * 1000;  //1000是接地电阻1k
    } 

    return temp;
}

//将电压转成电阻
//输入的 VDD = 电阻1k对应的分压
//需要 VDD * 2,用于计算出电源电压
double V_Convert_R(uint32_t vdd,uint32_t v)
{
    double temp1;
    double temp2;
    
    // printf("VDD: %d, V: %d \n",vdd,v);
    temp1 = vdd;
    temp2 = v;
    temp2 = (temp1 / temp2);
    // printf("Kp (VDD / V): %f\n",temp2);
    temp2 *= 2.0; //VDD = 2 * 1k电阻对应的分压

    temp2 *= 1000.0;
    temp2 -= 1000.0;
    return temp2;
}

//将摄氏度转华氏度
double CTemp_Convert_FTemp(double F_temp)
{
    F_temp *= 1.8;
    F_temp += 32;

    return F_temp;
}

//Pt1000电阻转C温度值
//Pt1000铂电阻的一元二次解温度公式
//输入电阻值, 例如 1000.000
//返回 C温度(有符号值),有效位小数点后2位
double Quadratic(double R_x)
{
    double a;
    double b;
    double c;
    double x;

    if(R_x <= 803)
    { //判断Pt1000电阻 <= 100, 就认为铂电阻短路
        x = -222.935332;
        Pt1000_State = Pt1000_Short;
    }
    else if (R_x >= (2120 + 1000)) //Pt1000电阻,本身测量范围:[-58,572]F; [-50,300]C; [803.063,2120.515]Ω
    { //判断Pt1000电阻 >= 5k, 认为电阻开路, 肉探针测量的最高阻值不到5k
        x = 1256.896275;
        Pt1000_State = Pt1000_Open;
    }
    else
    {
        a = 1000.000;
        a *= -0.0000005775;
        b = 1000.000;
        b *= 0.0039083;
        c = 1000.000 - R_x;
        
        x = b * b - (4.0 * a * c);
        if(InvSqrt(x) != 0) x = (-b + 1.0/InvSqrt(x)) / (2.0 * a);
        
        Pt1000_State = Pt1000_Normal;
    }

    return x;
}

//输入: Pt1000电阻, 输出: F/C温度值
double Quadratic_FC(double R_x)
{
    double temp;
    
    temp = Quadratic(R_x);
    if(UI_System.Grill_Unit == Unit_F)
    {
        temp = CTemp_Convert_FTemp(temp);
    }

    return temp;
}
